using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;

namespace Microsoft.Office.OneNote
{
    using ErrorCodes = NativeErrorCodes;
    using ErrorMessages = Exceptions.Messages;

    [Serializable]
    public class OneNoteException : ExternalException
    {
        #region Native error messages

        private static readonly string[] Messages = new string[]
        {
            ErrorMessages.MALFORMED_XML_ERROR,
            ErrorMessages.INVALID_XML_ERROR,
            ErrorMessages.ERROR_CREATING_SECTION,
            ErrorMessages.ERROR_OPENING_SECTION,
            ErrorMessages.SECTION_DOES_NOT_EXIST_ERROR,
            ErrorMessages.PAGE_DOES_NOT_EXIST_ERROR,
            ErrorMessages.FILE_DOES_NOT_EXIST_ERROR,
            ErrorMessages.ERROR_INSERTING_IMAGE,
            ErrorMessages.ERROR_INSERTING_INK,
            ErrorMessages.ERROR_INSERTING_HTML,
            ErrorMessages.ERROR_NAVIGATING_TO_PAGE,
            ErrorMessages.SECTION_IS_READ_ONLY,
            ErrorMessages.PAGE_IS_READ_ONLY,
            ErrorMessages.ERROR_INSERTING_OUTLINETEXT,
            ErrorMessages.PAGE_OBJECT_DOES_NOT_EXIST_ON_PAGE,
            ErrorMessages.BINARY_OBJECT_DOES_NOT_EXIST_ON_PAGE,
            ErrorMessages.LAST_MODIFIED_DATE_DID_NOT_MATCH,
            ErrorMessages.GROUP_DOES_NOT_EXIST_IN_SECTION,
            ErrorMessages.PAGE_NOT_IN_SPECFIED_GROUP,
            ErrorMessages.NO_ACTIVE_SELECTION_OR_IP,
            ErrorMessages.OBJECT_DOES_NOT_XIST,
            ErrorMessages.NOTEBOOK_DOES_NOT_EXIST,
            ErrorMessages.INSERTING_FILE,
            ErrorMessages.INVALID_NAME,
            ErrorMessages.FOLDER_DOES_NOT_EXIST,
            ErrorMessages.INVALID_QUERY,
            ErrorMessages.FILE_ALREADY_EXISTS,
            ErrorMessages.SECTION_ENCRYPTED_AND_LOCKED,
            ErrorMessages.DISABLED_BY_POLICY,
            ErrorMessages.NOT_YET_SYNCHRONIZED,
            ErrorMessages.LEGACY_SECTION,
        };

        #endregion

        public OneNoteException()
        {
        }

        public OneNoteException(string message)
            : base(message)
        {
        }

        public OneNoteException(string message, int errorCode)
            : base(message, errorCode)
        {
        }

        public OneNoteException(string message, Exception inner)
            : base(message, inner)
        {
        }

        protected OneNoteException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }

        internal static Exception GetExceptionForHR(int errorCode)
        {
            if (errorCode >= ErrorCodes.OneNoteFirst && errorCode <= ErrorCodes.OneNoteLast)
            {
                return new OneNoteException(Messages[errorCode - ErrorCodes.OneNoteFirst], errorCode);
            }
            
            return Marshal.GetExceptionForHR(errorCode);
        }
    }
}
